bitkeeper revision 1.1159.170.1 (418fbcfftbJRf270n_KReJDuXIouGg)
authorkaf24@freefall.cl.cam.ac.uk <kaf24@freefall.cl.cam.ac.uk>
Mon, 8 Nov 2004 18:37:51 +0000 (18:37 +0000)
committerkaf24@freefall.cl.cam.ac.uk <kaf24@freefall.cl.cam.ac.uk>
Mon, 8 Nov 2004 18:37:51 +0000 (18:37 +0000)
Rejig the layout of saved activations on Xen's stack. Touches a bunch
of stuff but things are generally a bit cleaner now. Should be easier
to integrate vm86 support, and I'm now ready to do bigger changes to
the Xen->guest exit code.

.rootkeys
xen/arch/x86/traps.c
xen/arch/x86/x86_32/entry.S
xen/include/asm-x86/irq.h
xen/include/asm-x86/x86_32/asm_defns.h [new file with mode: 0644]
xen/include/asm-x86/x86_32/current.h
xen/include/asm-x86/x86_32/regs.h
xen/include/public/arch-x86_32.h
xen/include/public/dom0_ops.h
xen/include/xen/sched.h

index 0b9dde39da93bede368d27f5aad6c7bf93eb689d..2a93a73caca7b0487b4ab557b2aa2673c3276f59 100644 (file)
--- a/.rootkeys
+++ b/.rootkeys
 3ddb79c3ezddh34MdelJpa5tNR00Dw xen/include/asm-x86/system.h
 3ddb79c4HugMq7IYGxcQKFBpKwKhzA xen/include/asm-x86/types.h
 40cf1596saFaHD5DC5zvrSn7CDCWGQ xen/include/asm-x86/uaccess.h
+418fbcfe_WliJPToeVM-9VStvym-hw xen/include/asm-x86/x86_32/asm_defns.h
 3ddb79c2ADvRmdexd9y3AYK9_NTx-Q xen/include/asm-x86/x86_32/current.h
 3ddb79c3mbqEM7QQr3zVq7NiBNhouA xen/include/asm-x86/x86_32/regs.h
 3e7f358aG11EvMI9VJ4_9hD4LUO7rQ xen/include/asm-x86/x86_32/string.h
index 8f6cb3c69458c41cb5fad7bfb78c28f528394f08..3f7793c36ebf68050284146f6d3df3348b2af512 100644 (file)
@@ -166,14 +166,25 @@ void show_stack(unsigned long *esp)
 void show_registers(struct xen_regs *regs)
 {
     unsigned long esp;
-    unsigned short ss;
+    unsigned short ss, ds, es, fs, gs;
 
-    esp = (unsigned long)(&regs->esp);
-    ss  = __HYPERVISOR_DS;
     if ( regs->xcs & 3 )
     {
         esp = regs->esp;
         ss  = regs->xss & 0xffff;
+        ds  = regs->xds & 0xffff;
+        es  = regs->xes & 0xffff;
+        fs  = regs->xfs & 0xffff;
+        gs  = regs->xgs & 0xffff;
+    }
+    else
+    {
+        esp = (unsigned long)(&regs->esp);
+        ss  = __HYPERVISOR_DS;
+        ds  = __HYPERVISOR_DS;
+        es  = __HYPERVISOR_DS;
+        fs  = __HYPERVISOR_DS;
+        gs  = __HYPERVISOR_DS;
     }
 
     printk("CPU:    %d\nEIP:    %04x:[<%08lx>]      \nEFLAGS: %08lx\n",
@@ -183,8 +194,7 @@ void show_registers(struct xen_regs *regs)
     printk("esi: %08lx   edi: %08lx   ebp: %08lx   esp: %08lx\n",
            regs->esi, regs->edi, regs->ebp, esp);
     printk("ds: %04x   es: %04x   fs: %04x   gs: %04x   ss: %04x\n",
-           regs->xds & 0xffff, regs->xes & 0xffff, 
-           regs->xfs & 0xffff, regs->xgs & 0xffff, ss);
+           ds, es, fs, gs, ss);
 
     show_stack(&regs->esp);
 } 
@@ -230,7 +240,6 @@ static inline void do_trap(int trapnr, char *str,
     {
         DPRINTK("Trap %d: %08lx -> %08lx\n", trapnr, regs->eip, fixup);
         regs->eip = fixup;
-        regs->xds = regs->xes = regs->xfs = regs->xgs = __HYPERVISOR_DS;
         return;
     }
 
@@ -394,7 +403,6 @@ asmlinkage void do_page_fault(struct xen_regs *regs, long error_code)
         if ( !d->mm.shadow_mode )
             DPRINTK("Page fault: %08lx -> %08lx\n", regs->eip, fixup);
         regs->eip = fixup;
-        regs->xds = regs->xes = regs->xfs = regs->xgs = __HYPERVISOR_DS;
         return;
     }
 
@@ -509,7 +517,6 @@ asmlinkage void do_general_protection(struct xen_regs *regs, long error_code)
     {
         DPRINTK("GPF (%04lx): %08lx -> %08lx\n", error_code, regs->eip, fixup);
         regs->eip = fixup;
-        regs->xds = regs->xes = regs->xfs = regs->xgs = __HYPERVISOR_DS;
         return;
     }
 
index 9a792d19f9ee65a70452add4bfa1797d13379fe9..474b399b59932a207ea10025c088b7e462222faa 100644 (file)
 #include <xen/config.h>
 #include <xen/errno.h>
 #include <xen/softirq.h>
+#include <asm/x86_32/asm_defns.h>
 #include <public/xen.h>
 
-EBX            = 0x00
-ECX            = 0x04
-EDX            = 0x08
-ESI            = 0x0C
-EDI            = 0x10
-EBP            = 0x14
-EAX            = 0x18
-DS             = 0x1C
-ES             = 0x20
-FS              = 0x24
-GS              = 0x28
-ORIG_EAX       = 0x2C
-EIP            = 0x30
-CS             = 0x34
-EFLAGS         = 0x38
-OLDESP         = 0x3C
-OLDSS          = 0x40
-
-/* Offsets in domain structure */
-PROCESSOR       =  0
-SHARED_INFO     =  4
-EVENT_SEL       =  8
-EVENT_ADDR      = 12
-FAILSAFE_BUFFER = 16
-FAILSAFE_SEL    = 32
-FAILSAFE_ADDR   = 36
-
-/* Offsets in shared_info_t */
-#define UPCALL_PENDING /* 0 */
-#define UPCALL_MASK       1
-
-/* Offsets in guest_trap_bounce */
-GTB_ERROR_CODE   =  0
-GTB_CR2          =  4
-GTB_FLAGS        =  8
-GTB_CS           = 10
-GTB_EIP          = 12
-GTBF_TRAP        =  1
-GTBF_TRAP_NOCODE =  2
-GTBF_TRAP_CR2    =  4
-                        
-CF_MASK                = 0x00000001
-IF_MASK                = 0x00000200
-NT_MASK                = 0x00004000
-        
-#define SAVE_ALL_NOSEGREGS \
-        cld; \
-        pushl %gs; \
-        pushl %fs; \
-        pushl %es; \
-        pushl %ds; \
-        pushl %eax; \
-        pushl %ebp; \
-        pushl %edi; \
-        pushl %esi; \
-        pushl %edx; \
-        pushl %ecx; \
-        pushl %ebx; \
-
-#define SAVE_ALL \
-        SAVE_ALL_NOSEGREGS \
-        movl $(__HYPERVISOR_DS),%edx; \
-        movl %edx,%ds; \
-        movl %edx,%es; \
-        movl %edx,%fs; \
-        movl %edx,%gs; \
-        sti;
-
 #define GET_CURRENT(reg)   \
         movl $4096-4, reg; \
         orl  %esp, reg;    \
@@ -226,17 +159,10 @@ multicall_fixup1:
                 
         ALIGN
 restore_all_guest:
-        # First, may need to restore %ds if clobbered by create_bounce_frame
-        pushl %ss
-        popl  %ds
-        # Second, create a failsafe copy of DS,ES,FS,GS in case any are bad
-        leal  DS(%esp),%esi
-        leal  FAILSAFE_BUFFER(%ebx),%edi
-        movsl
-        movsl
-        movsl
-        movsl
-        # Finally, restore guest registers -- faults will cause failsafe
+1:     movl XREGS_ds(%esp),%ds
+2:     movl XREGS_es(%esp),%es
+3:     movl XREGS_fs(%esp),%fs
+4:     movl XREGS_gs(%esp),%gs
         popl %ebx
        popl %ecx
        popl %edx
@@ -244,62 +170,50 @@ restore_all_guest:
        popl %edi
        popl %ebp
        popl %eax
-1:     popl %ds
-2:     popl %es
-3:     popl %fs
-4:     popl %gs
         addl $4,%esp
 5:      iret
 .section .fixup,"ax"
-10:     subl $4,%esp
-        pushl %gs
-9:      pushl %fs
-8:      pushl %es
-7:      pushl %ds
-6:      pushl %eax
+6:      subl $4,%esp
+        pushl %eax
        pushl %ebp
        pushl %edi
        pushl %esi
        pushl %edx
        pushl %ecx
        pushl %ebx
-       pushl %ss
-       popl  %ds
-       pushl %ss
-       popl  %es
-       jmp  failsafe_callback
+7:      SET_XEN_SEGMENTS
+        jmp failsafe_callback
 .previous
 .section __ex_table,"a"
        .align 4
-       .long 1b,6b
+       .long 1b,7b
        .long 2b,7b
-       .long 3b,8b
-       .long 4b,9b
-       .long 5b,10b
+       .long 3b,7b
+       .long 4b,7b
+       .long 5b,6b
 .previous
 
 /* No special register assumptions */
 failsafe_callback:
         GET_CURRENT(%ebx)
-        movl PROCESSOR(%ebx),%eax
+        movl DOMAIN_processor(%ebx),%eax
         shl  $4,%eax
         lea  guest_trap_bounce(%eax),%edx
-        movl FAILSAFE_ADDR(%ebx),%eax
-        movl %eax,GTB_EIP(%edx)
-        movl FAILSAFE_SEL(%ebx),%eax
-        movw %ax,GTB_CS(%edx)
+        movl DOMAIN_failsafe_addr(%ebx),%eax
+        movl %eax,GTB_eip(%edx)
+        movl DOMAIN_failsafe_sel(%ebx),%eax
+        movw %ax,GTB_cs(%edx)
         call create_bounce_frame
         subl $16,%esi                # add DS/ES/FS/GS to failsafe stack frame
-        leal FAILSAFE_BUFFER(%ebx),%ebp
-        movl  0(%ebp),%eax           # DS
-FAULT1: movl %eax,(%esi) 
-        movl  4(%ebp),%eax           # ES
-FAULT2: movl %eax,4(%esi)
-        movl  8(%ebp),%eax           # FS
-FAULT3: movl %eax,8(%esi) 
-        movl 12(%ebp),%eax           # GS
-FAULT4: movl %eax,12(%esi)
-        movl %esi,OLDESP(%esp)
+        movl XREGS_ds(%esp),%eax
+FAULT1: movl %eax,%gs:(%esi) 
+        movl XREGS_es(%esp),%eax
+FAULT2: movl %eax,%gs:4(%esi)
+        movl XREGS_fs(%esp),%eax
+FAULT3: movl %eax,%gs:8(%esi) 
+        movl XREGS_gs(%esp),%eax
+FAULT4: movl %eax,%gs:12(%esi)
+        movl %esi,XREGS_esp(%esp)
         popl %ebx
         popl %ecx
         popl %edx
@@ -307,15 +221,10 @@ FAULT4: movl %eax,12(%esi)
         popl %edi
         popl %ebp
         popl %eax
-        addl $20,%esp                # skip DS/ES/FS/GS/ORIG_EAX
+        addl $4,%esp
 FAULT5: iret 
 
-
         ALIGN
-# Simple restore -- we should never fault as we we will only interrupt ring 0
-# when sane values have been placed in all registers. The only exception is
-# NMI, which may interrupt before good values have been placed in DS-GS.
-# The NMI return code deals with this problem itself.
 restore_all_xen:
        popl %ebx
        popl %ecx
@@ -324,10 +233,6 @@ restore_all_xen:
        popl %edi
        popl %ebp
        popl %eax
-       popl %ds
-       popl %es
-       popl %fs
-       popl %gs
         addl $4,%esp
         iret
 
@@ -335,37 +240,38 @@ restore_all_xen:
 ENTRY(hypercall)
         pushl %eax                     # save orig_eax
        SAVE_ALL
-       GET_CURRENT(%ebx)
+        sti
+        GET_CURRENT(%ebx)
        andl $(NR_hypercalls-1),%eax
        call *SYMBOL_NAME(hypercall_table)(,%eax,4)
 
 ret_from_hypercall:
-        movl %eax,EAX(%esp)            # save the return value
+        movl %eax,XREGS_eax(%esp)              # save the return value
 
 test_all_events:
         xorl %ecx,%ecx
         notl %ecx
         cli                             # tests must not race interrupts
 /*test_softirqs:*/  
-        movl PROCESSOR(%ebx),%eax
+        movl DOMAIN_processor(%ebx),%eax
         shl  $6,%eax                    # sizeof(irq_cpustat) == 64
         test %ecx,SYMBOL_NAME(irq_stat)(%eax,1)
         jnz  process_softirqs
 /*test_guest_events:*/
-        movl SHARED_INFO(%ebx),%eax
-        testb $0xFF,UPCALL_MASK(%eax)
+        movl DOMAIN_shared_info(%ebx),%eax
+        testb $0xFF,SHINFO_upcall_mask(%eax)
         jnz  restore_all_guest
-        testb $0xFF,UPCALL_PENDING(%eax)
+        testb $0xFF,SHINFO_upcall_pending(%eax)
         jz   restore_all_guest
-        movb $1,UPCALL_MASK(%eax)       # Upcalls are masked during delivery
+        movb $1,SHINFO_upcall_mask(%eax) # Upcalls are masked during delivery
 /*process_guest_events:*/
-        movl PROCESSOR(%ebx),%edx
-        shl  $4,%edx                    # sizeof(guest_trap_bounce) == 16
+        movl DOMAIN_processor(%ebx),%edx
+        shl  $4,%edx                     # sizeof(guest_trap_bounce) == 16
         lea  guest_trap_bounce(%edx),%edx
-        movl EVENT_ADDR(%ebx),%eax
-        movl %eax,GTB_EIP(%edx)
-        movl EVENT_SEL(%ebx),%eax
-        movw %ax,GTB_CS(%edx)
+        movl DOMAIN_event_addr(%ebx),%eax
+        movl %eax,GTB_eip(%edx)
+        movl DOMAIN_event_sel(%ebx),%eax
+        movw %ax,GTB_cs(%edx)
         call create_bounce_frame
         jmp  restore_all_guest
 
@@ -375,16 +281,16 @@ process_softirqs:
         call SYMBOL_NAME(do_softirq)
         jmp  test_all_events
                 
-/* CREATE A BASIC EXCEPTION FRAME ON GUEST OS (RING-1) STACK:         */
-/*   {EIP, CS, EFLAGS, [ESP, SS]}                                     */
-/* %edx == guest_trap_bounce, %ebx == task_struct                     */
-/* %eax,%ecx are clobbered. %ds:%esi contain new OLDSS/OLDESP.        */
+/* CREATE A BASIC EXCEPTION FRAME ON GUEST OS (RING-1) STACK:            */
+/*   {EIP, CS, EFLAGS, [ESP, SS]}                                        */
+/* %edx == guest_trap_bounce, %ebx == task_struct                        */
+/* %eax,%ecx are clobbered. %gs:%esi contain new XREGS_ss/XREGS_esp. */
 create_bounce_frame:        
-        mov  CS+4(%esp),%cl
+        mov  XREGS_cs+4(%esp),%cl
         test $2,%cl
         jz   1f /* jump if returning to an existing ring-1 activation */
         /* obtain ss/esp from TSS -- no current ring-1 activations */
-        movl PROCESSOR(%ebx),%eax
+        movl DOMAIN_processor(%ebx),%eax
         /* next 4 lines multiply %eax by 8320, which is sizeof(tss_struct) */
         movl %eax, %ecx
         shll $7, %ecx
@@ -392,38 +298,37 @@ create_bounce_frame:
         addl %ecx,%eax
         addl $init_tss + 12,%eax
         movl (%eax),%esi /* tss->esp1 */
-FAULT6: movl 4(%eax),%ds /* tss->ss1  */
+FAULT6: movl 4(%eax),%gs /* tss->ss1  */
         /* base of stack frame must contain ss/esp (inter-priv iret) */
         subl $8,%esi
-        movl OLDESP+4(%esp),%eax
-FAULT7: movl %eax,(%esi) 
-        movl OLDSS+4(%esp),%eax
-FAULT8: movl %eax,4(%esi) 
+        movl XREGS_esp+4(%esp),%eax
+FAULT7: movl %eax,%gs:(%esi) 
+        movl XREGS_ss+4(%esp),%eax
+FAULT8: movl %eax,%gs:4(%esi) 
         jmp 2f
 1:      /* obtain ss/esp from oldss/oldesp -- a ring-1 activation exists */
-        movl OLDESP+4(%esp),%esi
-FAULT9: movl OLDSS+4(%esp),%d
+        movl XREGS_esp+4(%esp),%esi
+FAULT9: movl XREGS_ss+4(%esp),%g
 2:      /* Construct a stack frame: EFLAGS, CS/EIP */
         subl $12,%esi
-        movl EIP+4(%esp),%eax
-FAULT10:movl %eax,(%esi) 
-        movl CS+4(%esp),%eax
-FAULT11:movl %eax,4(%esi) 
-        movl EFLAGS+4(%esp),%eax
-FAULT12:movl %eax,8(%esi)
+        movl XREGS_eip+4(%esp),%eax
+FAULT10:movl %eax,%gs:(%esi) 
+        movl XREGS_cs+4(%esp),%eax
+FAULT11:movl %eax,%gs:4(%esi) 
+        movl XREGS_eflags+4(%esp),%eax
+FAULT12:movl %eax,%gs:8(%esi)
         /* Rewrite our stack frame and return to ring 1. */
         /* IA32 Ref. Vol. 3: TF, VM, RF and NT flags are cleared on trap. */
         andl $0xfffcbeff,%eax
-        movl %eax,EFLAGS+4(%esp)
-        movl %ds,OLDSS+4(%esp)
-        movl %esi,OLDESP+4(%esp)
-        movzwl %es:GTB_CS(%edx),%eax
-        movl %eax,CS+4(%esp)
-        movl %es:GTB_EIP(%edx),%eax
-        movl %eax,EIP+4(%esp)
+        movl %eax,XREGS_eflags+4(%esp)
+        movl %gs,XREGS_ss+4(%esp)
+        movl %esi,XREGS_esp+4(%esp)
+        movzwl GTB_cs(%edx),%eax
+        movl %eax,XREGS_cs+4(%esp)
+        movl GTB_eip(%edx),%eax
+        movl %eax,XREGS_eip+4(%esp)
         ret
-        
-                              
+
 .section __ex_table,"a"
         .align 4
         .long FAULT1, crash_domain_fixup3 # Fault writing to ring-1 stack
@@ -447,44 +352,41 @@ FAULT12:movl %eax,8(%esi)
 crash_domain_fixup1:
         subl  $4,%esp
         SAVE_ALL
+        sti
         jmp   domain_crash
 crash_domain_fixup2:
         addl  $4,%esp                     
 crash_domain_fixup3:
-        pushl %ss
-        popl  %ds
         jmp   domain_crash
 .previous
 
         ALIGN
 process_guest_exception_and_events:        
-        movl PROCESSOR(%ebx),%eax
+        movl DOMAIN_processor(%ebx),%eax
         shl  $4,%eax
         lea  guest_trap_bounce(%eax),%edx
-        testb $~0,GTB_FLAGS(%edx)
+        testb $~0,GTB_flags(%edx)
         jz   test_all_events
         call create_bounce_frame        # just the basic frame
-        mov  %es:GTB_FLAGS(%edx),%cl
+        mov  GTB_flags(%edx),%cl
         test $GTBF_TRAP_NOCODE,%cl
         jnz  2f
         subl $4,%esi                    # push error_code onto guest frame
-        movl %es:GTB_ERROR_CODE(%edx),%eax
-FAULT13:movl %eax,(%esi)
+        movl GTB_error_code(%edx),%eax
+FAULT13:movl %eax,%gs:(%esi)
         test $GTBF_TRAP_CR2,%cl
         jz   1f
         subl $4,%esi                    # push %cr2 onto guest frame
-        movl %es:GTB_CR2(%edx),%eax
-FAULT14:movl %eax,(%esi)
-1:      movl %esi,OLDESP(%esp)        
-2:      push %es                        # unclobber %ds
-        pop  %ds 
-        movb $0,GTB_FLAGS(%edx)
+        movl GTB_cr2(%edx),%eax
+FAULT14:movl %eax,%gs:(%esi)
+1:      movl %esi,XREGS_esp(%esp)        
+2:      movb $0,GTB_flags(%edx)
         jmp  test_all_events
 
         ALIGN
 ENTRY(ret_from_intr)
        GET_CURRENT(%ebx)
-        movb CS(%esp),%al
+        movb XREGS_cs(%esp),%al
        testb $3,%al    # return to non-supervisor?
        jne test_all_events
        jmp restore_all_xen
@@ -494,36 +396,31 @@ ENTRY(divide_error)
        pushl $ SYMBOL_NAME(do_divide_error)
        ALIGN
 error_code:
-       pushl %fs
-       pushl %es
-       pushl %ds
-       pushl %eax
-       xorl  %eax,%eax
-       pushl %ebp
+       cld
+       pushl %ebp
        pushl %edi
        pushl %esi
        pushl %edx
-       decl  %eax                      # eax = -1
        pushl %ecx
        pushl %ebx
-       cld
-       movl  %gs,%ecx
-       movl  ORIG_EAX(%esp), %esi      # get the error code
-       movl  GS(%esp), %edi            # get the function address
-       movl  %eax, ORIG_EAX(%esp)
-       movl  %ecx, GS(%esp)
-       movl  $(__HYPERVISOR_DS),%edx
-       movl  %edx,%ds
-       movl  %edx,%es
-       movl  %edx,%fs
-       movl  %edx,%gs
+        movb XREGS_cs(%esp),%bl
+        testb $3,%bl
+        je   1f
+        movl %ds,XREGS_ds(%esp)
+        movl %es,XREGS_es(%esp)
+        movl %fs,XREGS_fs(%esp)
+        movl %gs,XREGS_gs(%esp)
+1:      SET_XEN_SEGMENTS
+       movl  XREGS_orig_eax(%esp),%esi         # get the error code
+       movl  XREGS_eax(%esp),%edi              # get the function address
+       movl  %eax,XREGS_eax(%esp)
        movl  %esp,%edx
        pushl %esi                      # push the error code
        pushl %edx                      # push the xen_regs pointer
        GET_CURRENT(%ebx)
-       call  *%edi
+        call  *%edi
         addl  $8,%esp
-        movb  CS(%esp),%al
+        movb  XREGS_cs(%esp),%al
        testb $3,%al
        je    restore_all_xen
         jmp   process_guest_exception_and_events
@@ -628,21 +525,21 @@ ENTRY(nmi)
         # In all other cases we bail without touching DS-GS, as we have
         # interrupted an enclosing Xen activation in tricky prologue or
         # epilogue code.
-        movb  CS(%esp),%al
+        movb  XREGS_cs(%esp),%al
        testb $3,%al
         jne   do_watchdog_tick
-        movl  DS(%esp),%eax
+        movl  XREGS_ds(%esp),%eax
         cmpw  $(__HYPERVISOR_DS),%ax
-        jne   nmi_badseg
-        movl  ES(%esp),%eax
+        jne   restore_all_xen
+        movl  XREGS_es(%esp),%eax
         cmpw  $(__HYPERVISOR_DS),%ax
-        jne   nmi_badseg
-        movl  FS(%esp),%eax
+        jne   restore_all_xen
+        movl  XREGS_fs(%esp),%eax
         cmpw  $(__HYPERVISOR_DS),%ax
-        jne   nmi_badseg
-        movl  GS(%esp),%eax
+        jne   restore_all_xen
+        movl  XREGS_gs(%esp),%eax
         cmpw  $(__HYPERVISOR_DS),%ax
-        jne   nmi_badseg
+        jne   restore_all_xen
 
 do_watchdog_tick:
         movl  $(__HYPERVISOR_DS),%edx
@@ -653,34 +550,23 @@ do_watchdog_tick:
        pushl %edx   # regs
         call  SYMBOL_NAME(do_nmi)
        addl  $8,%esp
-        movb  CS(%esp),%al
+        movb  XREGS_cs(%esp),%al
        testb $3,%al
        je    restore_all_xen
         GET_CURRENT(%ebx)
         jmp   restore_all_guest
 
-nmi_badseg:
-       popl %ebx
-       popl %ecx
-       popl %edx
-       popl %esi
-       popl %edi
-       popl %ebp
-       popl %eax
-        addl $20,%esp
-        iret
-
 nmi_parity_err:
         # Clear and disable the parity-error line
         andb $0xf,%al
         orb  $0x4,%al
         outb %al,$0x61
         cmpb $'i',%ss:SYMBOL_NAME(opt_nmi) # nmi=ignore
-        je   nmi_badseg
+        je   restore_all_xen
         bts  $0,%ss:SYMBOL_NAME(nmi_softirq_reason)
         bts  $NMI_SOFTIRQ,%ss:SYMBOL_NAME(irq_stat)
         cmpb $'d',%ss:SYMBOL_NAME(opt_nmi) # nmi=dom0
-        je   nmi_badseg
+        je   restore_all_xen
         movl $(__HYPERVISOR_DS),%edx       # nmi=fatal
         movl %edx,%ds
         movl %edx,%es
@@ -696,11 +582,11 @@ nmi_io_err:
         orb  $0x8,%al
         outb %al,$0x61
         cmpb $'i',%ss:SYMBOL_NAME(opt_nmi) # nmi=ignore
-        je   nmi_badseg
+        je   restore_all_xen
         bts  $1,%ss:SYMBOL_NAME(nmi_softirq_reason)
         bts  $NMI_SOFTIRQ,%ss:SYMBOL_NAME(irq_stat)
         cmpb $'d',%ss:SYMBOL_NAME(opt_nmi) # nmi=dom0
-        je   nmi_badseg
+        je   restore_all_xen
         movl $(__HYPERVISOR_DS),%edx       # nmi=fatal
         movl %edx,%ds
         movl %edx,%es
index 83c4c8f614bbbcda5b0a7c7f67013cad6e1daa5a..3b71f7f0a0a25639aac56d5a8aac8e2ab3e86e84 100644 (file)
@@ -5,6 +5,7 @@
 
 #include <xen/config.h>
 #include <asm/atomic.h>
+#include <asm/x86_32/asm_defns.h>
 
 extern void disable_irq(unsigned int);
 extern void disable_irq_nosync(unsigned int);
@@ -83,36 +84,6 @@ extern char _stext, _etext;
 
 #define IO_APIC_IRQ(x) (((x) >= 16) || ((1<<(x)) & io_apic_irqs))
 
-#define __STR(x) #x
-#define STR(x) __STR(x)
-
-#if defined(__i386__)
-
-#define SAVE_ALL \
-       "cld\n\t" \
-       "pushl %gs\n\t" \
-       "pushl %fs\n\t" \
-       "pushl %es\n\t" \
-       "pushl %ds\n\t" \
-       "pushl %eax\n\t" \
-       "pushl %ebp\n\t" \
-       "pushl %edi\n\t" \
-       "pushl %esi\n\t" \
-       "pushl %edx\n\t" \
-       "pushl %ecx\n\t" \
-       "pushl %ebx\n\t" \
-       "movl $" STR(__HYPERVISOR_DS) ",%edx\n\t" \
-       "movl %edx,%ds\n\t" \
-       "movl %edx,%es\n\t" \
-       "movl %edx,%fs\n\t" \
-       "movl %edx,%gs\n\t"
-
-#else
-
-#define SAVE_ALL
-
-#endif
-
 #define BUILD_SMP_INTERRUPT(x,v) XBUILD_SMP_INTERRUPT(x,v)
 #define XBUILD_SMP_INTERRUPT(x,v)\
 asmlinkage void x(void); \
diff --git a/xen/include/asm-x86/x86_32/asm_defns.h b/xen/include/asm-x86/x86_32/asm_defns.h
new file mode 100644 (file)
index 0000000..0f022d3
--- /dev/null
@@ -0,0 +1,122 @@
+#ifndef __ASM_DEFNS_H__
+#define __ASM_DEFNS_H__
+
+/* Offsets in 'struct xen_regs' --- AUTO-GENERATE ME! */
+#define XREGS_ebx      0x00
+#define XREGS_ecx      0x04
+#define XREGS_edx      0x08
+#define XREGS_esi      0x0C
+#define XREGS_edi      0x10
+#define XREGS_ebp      0x14
+#define XREGS_eax      0x18
+#define XREGS_orig_eax 0x1C
+#define XREGS_eip      0x20
+#define XREGS_cs       0x24
+#define XREGS_eflags   0x28
+#define XREGS_esp      0x2C
+#define XREGS_ss       0x30
+#define XREGS_es       0x34
+#define XREGS_ds       0x38
+#define XREGS_fs       0x3C
+#define XREGS_gs       0x40
+
+/* Offsets in 'struct domain' --- AUTO-GENERATE ME! */
+#define DOMAIN_processor       0
+#define DOMAIN_shared_info     4
+#define DOMAIN_event_sel       8
+#define DOMAIN_event_addr     12
+#define DOMAIN_failsafe_sel   16
+#define DOMAIN_failsafe_addr  20
+
+/* Offsets in shared_info_t --- AUTO-GENERATE ME! */
+#define SHINFO_upcall_pending /* 0 */
+#define SHINFO_upcall_mask       1
+
+/* Offsets in 'struct guest_trap_bounce' --- AUTO-GENERATE ME! */
+#define GTB_error_code    0
+#define GTB_cr2           4
+#define GTB_flags         8
+#define GTB_cs           10
+#define GTB_eip          12
+#define GTBF_TRAP         1
+#define GTBF_TRAP_NOCODE  2
+#define GTBF_TRAP_CR2     4
+
+/* EFLAGS masks. */
+#define CF_MASK 0x00000001
+#define IF_MASK 0x00000200
+#define NT_MASK 0x00004000
+
+#define __STR(x) #x
+#define STR(x) __STR(x)
+
+/* AUTO-GENERATE the following two cases (quoted vs. unquoted). */
+#ifndef __ASSEMBLY__
+
+#define __SAVE_ALL_PRE \
+        "cld;" \
+        "pushl %eax;" \
+        "pushl %ebp;" \
+        "pushl %edi;" \
+        "pushl %esi;" \
+        "pushl %edx;" \
+        "pushl %ecx;" \
+        "pushl %ebx;" \
+        "movb "STR(XREGS_cs)"(%esp),%al;" \
+        "testb $3,%al;" \
+        "je 1f;" \
+        "movl %ds,"STR(XREGS_ds)"(%esp);" \
+        "movl %es,"STR(XREGS_es)"(%esp);" \
+        "movl %fs,"STR(XREGS_fs)"(%esp);" \
+        "movl %gs,"STR(XREGS_gs)"(%esp);"
+
+#define SAVE_ALL_NOSEGREGS \
+        __SAVE_ALL_PRE \
+        "1:"
+
+#define SET_XEN_SEGMENTS \
+        "movl $("STR(__HYPERVISOR_DS)"),%edx;" \
+        "movl %edx,%ds;" \
+        "movl %edx,%es;"
+
+#define SAVE_ALL \
+        __SAVE_ALL_PRE \
+        SET_XEN_SEGMENTS \
+        "1:"
+
+#else
+
+#define __SAVE_ALL_PRE \
+        cld; \
+        pushl %eax; \
+        pushl %ebp; \
+        pushl %edi; \
+        pushl %esi; \
+        pushl %edx; \
+        pushl %ecx; \
+        pushl %ebx; \
+        movb XREGS_cs(%esp),%dl; \
+        testb $3,%dl; \
+        je 1f; \
+        movl %ds,XREGS_ds(%esp); \
+        movl %es,XREGS_es(%esp); \
+        movl %fs,XREGS_fs(%esp); \
+        movl %gs,XREGS_gs(%esp);
+
+#define SAVE_ALL_NOSEGREGS \
+        __SAVE_ALL_PRE \
+        1:
+
+#define SET_XEN_SEGMENTS \
+        movl $(__HYPERVISOR_DS),%edx; \
+        movl %edx,%ds; \
+        movl %edx,%es;
+
+#define SAVE_ALL \
+        __SAVE_ALL_PRE \
+        SET_XEN_SEGMENTS \
+        1:
+
+#endif
+
+#endif /* __ASM_DEFNS_H__ */
index 7d87b89d729f39e1c81b356644afae6bd26811d6..3450cd02cc8ea52f9342f730d236a230f61d9b18 100644 (file)
@@ -31,11 +31,17 @@ static inline execution_context_t *get_execution_context(void)
     return execution_context;
 }
 
+/*
+ * Get the top-of-stack, as stored in the per-CPU TSS. This is actually
+ * 20 bytes below the real top of the stack to allow space for:
+ *  domain pointer, DS, ES, FS, GS.
+ */
 static inline unsigned long get_stack_top(void)
 {
     unsigned long p;
-    __asm__ ( "orl %%esp,%0; andl $~3,%0" 
-              : "=r" (p) : "0" (STACK_SIZE-4) );
+    __asm__ ( "andl %%esp,%0; addl %2,%0" 
+              : "=r" (p)
+              : "0" (~(STACK_SIZE-1)), "i" (STACK_SIZE-20) );
     return p;
 }
 
index 18b1fdc66d09bc81440c7290e14761ff16539559..9adeb9d42024ff4d15a7ad87c4aed4340c0ddadc 100644 (file)
@@ -1,47 +1,51 @@
 #ifndef _I386_REGS_H
 #define _I386_REGS_H
 
-struct xen_regs {
-       long ebx;
-       long ecx;
-       long edx;
-       long esi;
-       long edi;
-       long ebp;
-       long eax;
-       int  xds;
-       int  xes;
-       int  xfs;
-       int  xgs;
-       long orig_eax;
-       long eip;
-       int  xcs;
-       long eflags;
-       long esp;
-       int  xss;
+struct xen_regs
+{
+    /* All saved activations contain the following fields. */
+    long ebx;
+    long ecx;
+    long edx;
+    long esi;
+    long edi;
+    long ebp;
+    long eax;
+    long orig_eax;
+    long eip;
+    int  xcs;
+    long eflags;
+
+    /* Only saved guest activations contain the following fields. */
+    long esp;
+    int  xss;
+    int  xes;
+    int  xds;
+    int  xfs;
+    int  xgs;
 };
 
 enum EFLAGS {
-        EF_CF   = 0x00000001,
-        EF_PF   = 0x00000004,
-        EF_AF   = 0x00000010,
-        EF_ZF   = 0x00000040,
-        EF_SF   = 0x00000080,
-        EF_TF   = 0x00000100,
-        EF_IE   = 0x00000200,
-        EF_DF   = 0x00000400,
-        EF_OF   = 0x00000800,
-        EF_IOPL = 0x00003000,
-        EF_IOPL_RING0 = 0x00000000,
-        EF_IOPL_RING1 = 0x00001000,
-        EF_IOPL_RING2 = 0x00002000,
-        EF_NT   = 0x00004000,   /* nested task */
-        EF_RF   = 0x00010000,   /* resume */
-        EF_VM   = 0x00020000,   /* virtual mode */
-        EF_AC   = 0x00040000,   /* alignment */
-        EF_VIF  = 0x00080000,   /* virtual interrupt */
-        EF_VIP  = 0x00100000,   /* virtual interrupt pending */
-        EF_ID   = 0x00200000,   /* id */
+    EF_CF   = 0x00000001,
+    EF_PF   = 0x00000004,
+    EF_AF   = 0x00000010,
+    EF_ZF   = 0x00000040,
+    EF_SF   = 0x00000080,
+    EF_TF   = 0x00000100,
+    EF_IE   = 0x00000200,
+    EF_DF   = 0x00000400,
+    EF_OF   = 0x00000800,
+    EF_IOPL = 0x00003000,
+    EF_IOPL_RING0 = 0x00000000,
+    EF_IOPL_RING1 = 0x00001000,
+    EF_IOPL_RING2 = 0x00002000,
+    EF_NT   = 0x00004000,   /* nested task */
+    EF_RF   = 0x00010000,   /* resume */
+    EF_VM   = 0x00020000,   /* virtual mode */
+    EF_AC   = 0x00040000,   /* alignment */
+    EF_VIF  = 0x00080000,   /* virtual interrupt */
+    EF_VIP  = 0x00100000,   /* virtual interrupt pending */
+    EF_ID   = 0x00200000,   /* id */
 };
 
 #endif
index 1287cdbe040f493974f1d9ab3cb9f0ab000197d5..dee8b783ef0b5a09dc1e137891b02e140329c136 100644 (file)
@@ -92,16 +92,16 @@ typedef struct
     unsigned long edi;
     unsigned long ebp;
     unsigned long eax;
-    unsigned long ds;
-    unsigned long es;
-    unsigned long fs;
-    unsigned long gs;
     unsigned long _unused;
     unsigned long eip;
     unsigned long cs;
     unsigned long eflags;
     unsigned long esp;
     unsigned long ss;
+    unsigned long es;
+    unsigned long ds;
+    unsigned long fs;
+    unsigned long gs;
 } PACKED execution_context_t;
 
 typedef u64 tsc_timestamp_t; /* RDTSC timestamp */
index e19141ca02e1c3c8fe0a5065d371fd5e5594d616..9339bcc318571af14432e0fb39f4801edb0954fb 100644 (file)
@@ -19,7 +19,7 @@
  * This makes sure that old versions of dom0 tools will stop working in a
  * well-defined way (rather than crashing the machine, for instance).
  */
-#define DOM0_INTERFACE_VERSION   0xAAAA0019
+#define DOM0_INTERFACE_VERSION   0xAAAA001A
 
 /************************************************************************/
 
index e44696bdbe5feddef168d45d91f5a485b3a92191..297df0e5374d52690e2245eb987e3a39682f3122 100644 (file)
@@ -75,15 +75,8 @@ struct domain
     unsigned long event_selector;    /* 08: entry CS  */
     unsigned long event_address;     /* 12: entry EIP */
 
-    /* Saved DS,ES,FS,GS immediately before return to guest OS. */
-    unsigned long failsafe_selectors[4]; /* 16-32 */ 
-
-    /*
-     * END OF FIRST CACHELINE. Stuff above is touched a lot!
-     */
-
-    unsigned long failsafe_selector; /* 32: entry CS  */
-    unsigned long failsafe_address;  /* 36: entry EIP */
+    unsigned long failsafe_selector; /* 16: entry CS  */
+    unsigned long failsafe_address;  /* 20: entry EIP */
 
     /*
      * From here on things can be added and shuffled without special attention